[Android] Improve TalkBack support#4222
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves Android TalkBack behavior across RNGH “pressable”/button primitives by ensuring press state transitions and accessibility actions still work even when TalkBack bypasses normal touch-event delivery.
Changes:
- Adjust Pressable’s Android + screen reader flow to drive
onPressInfromNATIVE_BEGIN(with optionalLONG_PRESS_TOUCHES_DOWN) and provide a synthetic event payload when needed. - Extend the Pressable state machine to support optional steps.
- Update Android button native code to better support long-press accessibility actions and to avoid activating native handlers when events are already passing through (
isPressedcase); also stop skipping events inNativeViewGestureHandlerunder TalkBack.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react-native-gesture-handler/src/v3/components/Pressable.tsx | Sends a synthetic event payload on NATIVE_BEGIN for Android TalkBack so the state machine can call onPressIn. |
| packages/react-native-gesture-handler/src/components/Pressable/utils.ts | Adds viewCenterToPressableEvent helper for synthetic Pressable events. |
| packages/react-native-gesture-handler/src/components/Pressable/StateMachine.tsx | Adds support for optional state-machine steps. |
| packages/react-native-gesture-handler/src/components/Pressable/stateDefinitions.ts | Updates Android accessibility state sequence to rely on NATIVE_BEGIN and make LONG_PRESS_TOUCHES_DOWN optional. |
| packages/react-native-gesture-handler/src/components/Pressable/Pressable.tsx | Mirrors the v3 Pressable TalkBack NATIVE_BEGIN synthetic payload behavior for LegacyPressable. |
| packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt | Adds long-press accessibility handling and refines native-handler activation logic for TalkBack. |
| packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt | Stops ignoring motion events for RNGH buttons when TalkBack is enabled. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| locationX: centerX, | ||
| locationY: centerY, | ||
| pageX: centerX, | ||
| pageY: centerY, | ||
| target: targetId, |
| locationX: centerX, | ||
| locationY: centerY, | ||
| pageX: centerX, | ||
| pageY: centerY, | ||
| target: targetId, |
| @@ -879,7 +898,8 @@ class RNGestureHandlerButtonViewManager : | |||
| // don't preform click when a child button is pressed (mainly to prevent sound effect of | |||
m-bert
left a comment
There was a problem hiding this comment.
I've looked into the provided example and it seems that Legacy Pressable doesn't work. Maybe it is on my side, but could you double-check that? 😅
What device was that? |
Pixel 7, same one I borrowed yesterday 😅 |
Description
Updates touchable components and
NativeViewGestureHandlerso that TalkBack is better supported:LONG_CLICKaccessibility action from buttons when definedNativeViewGestureHandlerwhen TalkBack is enabledisPressedistrue- this means that events are being passed through to the view, so the default flow should handle itPressablestate machine to allow optional statesPressablestate machine for Android with TalkBack to rely onNATIVE_BEGINandNATIVE_FINALIZEinstead ofLONG_PRESS_TOUCHES_DOWN- with TalkBack enabled, the activate action (double tap with button selected) doesn't dispatch events to view; instead, it runsperformClickdirectly - no events on view, noonTouchesDownTest plan